package p2p.tracker.client;

import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

import javax.swing.JFrame;

import p2p.tracker.client.GraphFrame;
import p2p.tracker.message.MessageListener;

/**
 * 
 * @author lukascho ClientManager is responsible for managing clients every
 *         client gets an unique id
 */
public class ClientManager {

	private static ClientManager instance;
	private ClientGraph clientGraph;

	private Map<UUID, MessageListener> messageListenerMap;

	private GraphListener listener;

	private ClientManager() {

		this.clientGraph = new ClientGraph("test");
		this.messageListenerMap = new HashMap<UUID, MessageListener>();
	}

	public static ClientManager getInstance() {

		if (instance == null) {
			instance = new ClientManager();
		} else {
			return instance;
		}
		return instance;

	}

	public synchronized void spawn(UUID uuid, Client a, Client b) {

		this.clientGraph.addEdge(a, b);

		this.hasFinished(uuid);

	}

	public synchronized void addListener(UUID uuid, MessageListener listener) {

		this.messageListenerMap.put(uuid, listener);

	}

	public synchronized void leave(UUID uuid, Client a) {

		this.clientGraph.removeEdge(a);
		this.hasFinished(uuid);

	}

	public synchronized void connected(UUID uuid, Client a) {

		this.hasFinished(uuid);

	}

	public synchronized void hasFinished(UUID uuid) {

		this.messageListenerMap.get(uuid).finishedMessageExecution();

	}

	public void addListener(GraphListener listener) {
		this.listener = listener;
	}

	public GraphListener getListener() {
		return listener;
	}

	public void setListener(GraphListener listener) {
		this.listener = listener;
	}
	
	public void createGraphVisualization() {
   	    GraphFrame gf = new GraphFrame();
   	    gf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
   	    gf.setSize(400, 320);
   	    gf.setVisible(true);
   	    
   	    /* example code - no functionality */
//	    gf.addNode("a"); gf.addNode("b"); gf.addNode("c");
//	    gf.addNode("d"); gf.addNode("e"); gf.addNode("f");
//	    gf.addNode("g"); gf.addNode("h"); gf.addNode("i");
//	    gf.addNode("j"); gf.addNode("k"); gf.addNode("l");
//	    gf.addEdge("test", "a", "b"); gf.addEdge("test", "d", "b");
//	    gf.addEdge("test", "j", "l"); gf.addEdge("test", "h", "d");
//	    gf.addEdge("test", "a", "c"); gf.addEdge("test", "k", "l");
//	    gf.addEdge("test", "j", "f"); gf.addEdge("test", "e", "f");
//	    gf.addEdge("test", "l", "i"); gf.addEdge("test", "g", "d");
	}
}
